import React, { useState, useCallback } from 'react'
import { Upload, Button, Card, Typography, Spin, message, Image, Space } from 'antd'
import { InboxOutlined, EyeOutlined, DeleteOutlined } from '@ant-design/icons'
import { CozeAPI } from '@coze/api'
import type { UploadProps, UploadFile } from 'antd'
import './index.less'

const { Dragger } = Upload
const { Title, Paragraph, Text } = Typography

interface CozeImageAnalyzerProps {
  cozeToken?: string
  botId?: string
  baseUrl?: string
  onAnalysisComplete?: (result: string) => void
}

interface AnalysisResult {
  content: string
  timestamp: number
  imageUrl: string
}

const CozeImageAnalyzer: React.FC<CozeImageAnalyzerProps> = ({
  cozeToken,
  botId,
  baseUrl = 'https://api.coze.cn',
  onAnalysisComplete,
}) => {
  const [fileList, setFileList] = useState<UploadFile[]>([])
  const [analyzing, setAnalyzing] = useState(false)
  const [analysisResult, setAnalysisResult] = useState<AnalysisResult | null>(null)
  const [previewVisible, setPreviewVisible] = useState(false)
  const [previewImage, setPreviewImage] = useState('')
  const [logs, setLogs] = useState<string[]>([])
  const [lastUploadedFile, setLastUploadedFile] = useState<{
    fileId: string
    imageUrl: string
  } | null>(null)
  const [analysisError, setAnalysisError] = useState<string | null>(null)

  // 调试模式检查
  const isDebugMode = localStorage.getItem('coze-debug') === 'true'
  const debugLog = (message: string, data?: any) => {
    const logEntry = `[${new Date().toLocaleTimeString()}] ${message} ${data ? JSON.stringify(data, null, 2) : ''}`

    if (isDebugMode) {
      console.log(message, data || '')
      setLogs(prev => [logEntry, ...prev.slice(0, 49)]) // 保留最近50条日志
    }
  }

  const clearLogs = () => {
    setLogs([])
    message.success('日志已清空')
  }

  const copyLogs = async () => {
    if (logs.length === 0) {
      message.warning('暂无日志可复制')
      return
    }

    try {
      const logText = logs.join('\n')
      await navigator.clipboard.writeText(logText)
      message.success(`已复制${logs.length}条日志到剪贴板`)
    } catch (error) {
      console.error('复制失败:', error)
      message.error('复制失败，请手动选择复制')
    }
  }

  const retryAnalysis = () => {
    if (!lastUploadedFile) {
      message.error('没有可重试的文件')
      return
    }

    debugLog('🔄 开始重试分析:', {
      fileId: lastUploadedFile.fileId,
      retryTime: new Date().toLocaleString(),
    })

    analyzeImage(lastUploadedFile.fileId, lastUploadedFile.imageUrl)
  }

  // 初始化Coze客户端
  const initCozeClient = useCallback(() => {
    if (!cozeToken) {
      message.error('请先配置Coze Token')
      return null
    }
    return new CozeAPI({
      token: cozeToken,
      baseURL: baseUrl,
      allowPersonalAccessTokenInBrowser: true,
    })
  }, [cozeToken, baseUrl])

  // 上传文件到Coze
  const uploadToCoze = async (file: File): Promise<string | null> => {
    const client = initCozeClient()
    if (!client) return null

    debugLog('🚀 开始上传文件到Coze:', {
      fileName: file.name,
      fileSize: `${(file.size / 1024 / 1024).toFixed(2)}MB`,
      fileType: file.type,
    })

    try {
      const response = await client.files.upload({ file })
      debugLog('✅ 文件上传成功:', {
        fileId: response.id,
        fileName: file.name,
        uploadTime: new Date().toLocaleString(),
      })
      message.success(`文件 "${file.name}" 上传成功`)
      return response.id
    } catch (error) {
      console.error('❌ 上传文件到Coze失败:', error)
      message.error('上传文件失败')
      return null
    }
  }

  // 分析图片内容
  const analyzeImage = async (fileId: string, imageUrl: string) => {
    const client = initCozeClient()
    if (!client || !botId) {
      message.error('请先配置Bot ID')
      return
    }

    debugLog('🔍 开始分析图片:', {
      fileId,
      botId,
      startTime: new Date().toLocaleString(),
    })

    setAnalyzing(true)
    setAnalysisError(null)
    setLastUploadedFile({ fileId, imageUrl })
    try {
      const messages = [
        {
          role: 'user' as const,
          content: [
            { type: 'file' as const, file_id: fileId },
            {
              type: 'text' as const,
              text: '分析一下',
            },
          ],
          content_type: 'object_string' as const,
        },
      ]

      debugLog('📤 发送分析请求:', {
        botId,
        messageCount: messages.length,
        requestTime: new Date().toLocaleString(),
      })

      const chatStream = await client.chat.stream({
        bot_id: botId,
        user_id: 'user-' + Date.now(),
        additional_messages: messages,
        auto_save_history: true,
      })

      let fullContent = ''
      let chunkCount = 0
      debugLog('📡 开始接收流式分析结果...')

      for await (const part of chatStream) {
        debugLog('📨 收到流式数据:', {
          event: part.event,
          timestamp: new Date().toLocaleString(),
          data: part.data ? JSON.stringify(part.data).substring(0, 200) : 'null',
        })

        if (part.event === 'conversation.message.delta') {
          const content = part.data.content
          if (content) {
            chunkCount++
            fullContent += content
            debugLog(`📝 分析内容更新 (第${chunkCount}块):`, {
              chunkLength: content.length,
              totalLength: fullContent.length,
              preview: content.substring(0, 50) + (content.length > 50 ? '...' : ''),
            })

            // 实时更新分析结果
            setAnalysisResult({
              content: fullContent,
              timestamp: Date.now(),
              imageUrl,
            })
          }
        } else if (part.event === 'error') {
          debugLog('❌ 收到错误事件:', {
            errorData: part.data,
            errorMessage: part.data?.msg || '未知错误',
            errorCode: part.data?.code || 'UNKNOWN',
          })

          const errorCode = part.data?.code
          const errorMsg = part.data?.msg || '分析过程中发生未知错误'

          // 根据错误代码提供更友好的错误信息
          let friendlyErrorMsg = errorMsg
          let suggestions = ''

          if (errorCode === 4101) {
            friendlyErrorMsg = 'Token权限不足，无法访问指定的Bot'
            suggestions = '请检查：1) Token是否正确 2) Bot ID是否正确 3) Token是否有访问该Bot的权限'
          } else if (errorCode === 4001) {
            friendlyErrorMsg = 'Token无效或已过期'
            suggestions = '请重新获取有效的API Token'
          } else if (errorCode === 4003) {
            friendlyErrorMsg = 'Bot不存在或无权访问'
            suggestions = '请检查Bot ID是否正确，或确认Bot是否已发布'
          }

          setAnalysisError(`${friendlyErrorMsg}${suggestions ? ` - ${suggestions}` : ''}`)
          message.error(`分析失败: ${friendlyErrorMsg}`)

          // 如果已经有部分内容，仍然保存
          if (fullContent) {
            const result = {
              content: fullContent + '\n\n[注意: 分析过程中断，内容可能不完整]',
              timestamp: Date.now(),
              imageUrl,
            }
            setAnalysisResult(result)
            onAnalysisComplete?.(result.content)
          }

          setAnalyzing(false)
          debugLog('🏁 分析流程因错误结束')
          return
        } else if (part.event === 'conversation.chat.completed') {
          debugLog('✅ 对话完成事件:', {
            usage: part.data?.usage,
            timestamp: new Date().toLocaleString(),
          })
        } else if (part.event === 'conversation.chat.failed') {
          debugLog('❌ 对话失败事件:', {
            failedData: part.data,
            errorCode: part.data?.last_error?.code,
            errorMsg: part.data?.last_error?.msg,
          })

          const errorCode = part.data?.last_error?.code
          const errorMsg = part.data?.last_error?.msg || '对话处理失败'

          let friendlyErrorMsg = errorMsg
          let suggestions = ''

          if (errorCode === 4000) {
            friendlyErrorMsg = '请求参数错误'
            suggestions = '请检查消息格式是否正确，或尝试使用不同的消息结构'
          } else if (errorCode === 4200) {
            friendlyErrorMsg = 'Bot模型端点不存在或不可用'
            suggestions = '请检查Bot配置中的模型设置，或联系管理员确认模型端点状态'
          }

          setAnalysisError(`${friendlyErrorMsg}${suggestions ? ` - ${suggestions}` : ''}`)
          message.error(`分析失败: ${friendlyErrorMsg}`)

          setAnalyzing(false)
          debugLog('🏁 分析流程因对话失败结束')
          return
        } else if (part.event === 'done') {
          debugLog('🎯 流式传输完成:', {
            finalData: part.data,
            timestamp: new Date().toLocaleString(),
          })
        } else {
          debugLog('ℹ️ 其他事件:', {
            event: part.event,
            data: part.data,
          })
        }
      }

      if (fullContent) {
        const result = {
          content: fullContent,
          timestamp: Date.now(),
          imageUrl,
        }
        debugLog('✅ 图片分析完成:', {
          totalChunks: chunkCount,
          contentLength: fullContent.length,
          completionTime: new Date().toLocaleString(),
          preview: fullContent.substring(0, 100) + (fullContent.length > 100 ? '...' : ''),
        })

        setAnalysisResult(result)
        setAnalysisError(null) // 清除错误状态
        onAnalysisComplete?.(fullContent)
        message.success(
          `图片分析完成！共接收${chunkCount}个数据块，分析内容长度：${fullContent.length}字符`
        )
      } else {
        debugLog('⚠️ 分析完成但未收到内容')
        message.warning('分析完成但未收到分析结果')
      }
    } catch (error) {
      console.error('❌ 分析图片失败:', error)
      debugLog('错误详情:', {
        message: error instanceof Error ? error.message : '未知错误',
        stack: error instanceof Error ? error.stack : undefined,
        timestamp: new Date().toLocaleString(),
      })
      message.error('分析图片失败，请查看控制台了解详情')
    } finally {
      setAnalyzing(false)
      debugLog('🏁 分析流程结束')
    }
  }

  // 处理文件上传
  const handleUpload: UploadProps['customRequest'] = async options => {
    const { file, onSuccess, onError } = options

    debugLog('📁 开始处理文件上传:', {
      fileName: (file as File).name,
      fileSize: `${((file as File).size / 1024 / 1024).toFixed(2)}MB`,
      fileType: (file as File).type,
      startTime: new Date().toLocaleString(),
    })

    try {
      // 创建预览URL
      const imageUrl = URL.createObjectURL(file as File)
      debugLog('🖼️ 创建预览URL成功:', imageUrl)

      // 上传到Coze
      const fileId = await uploadToCoze(file as File)
      if (!fileId) {
        debugLog('❌ 获取文件ID失败')
        onError?.(new Error('上传失败'))
        return
      }

      // 更新文件列表
      const uploadFile: UploadFile = {
        uid: Date.now().toString(),
        name: (file as File).name,
        status: 'done',
        url: imageUrl,
        response: { fileId },
      }

      debugLog('📋 更新文件列表:', {
        uid: uploadFile.uid,
        fileName: uploadFile.name,
        fileId,
      })

      setFileList([uploadFile])
      onSuccess?.(uploadFile)

      debugLog('🎯 开始自动分析图片...')
      // 自动开始分析
      await analyzeImage(fileId, imageUrl)
    } catch (error) {
      console.error('❌ 处理上传失败:', error)
      debugLog('上传错误详情:', {
        message: error instanceof Error ? error.message : '未知错误',
        stack: error instanceof Error ? error.stack : undefined,
        fileName: (file as File).name,
        timestamp: new Date().toLocaleString(),
      })
      onError?.(error as Error)
    }
  }

  // 预览图片
  const handlePreview = (file: UploadFile) => {
    setPreviewImage(file.url || file.preview || '')
    setPreviewVisible(true)
  }

  // 删除文件
  const handleRemove = (file: UploadFile) => {
    setFileList([])
    setAnalysisResult(null)
    if (file.url) {
      URL.revokeObjectURL(file.url)
    }
  }

  // 上传前验证
  const beforeUpload = (file: File) => {
    const isImage = file.type.startsWith('image/')
    if (!isImage) {
      message.error('只能上传图片文件!')
      return false
    }

    const isLt10M = file.size / 1024 / 1024 < 10
    if (!isLt10M) {
      message.error('图片大小不能超过10MB!')
      return false
    }

    return true
  }

  const toggleDebugMode = () => {
    const newDebugMode = !isDebugMode
    localStorage.setItem('coze-debug', newDebugMode.toString())
    message.info(`调试模式已${newDebugMode ? '开启' : '关闭'}，请刷新页面生效`)
  }

  return (
    <div className="coze-image-analyzer" style={{ padding: '20px' }}>
      <Card
        title="图片上传与分析"
        className="upload-area"
        style={{ marginBottom: '20px' }}
        extra={
          <Button size="small" type={isDebugMode ? 'primary' : 'default'} onClick={toggleDebugMode}>
            {isDebugMode ? '🐛 调试模式:开' : '🐛 调试模式:关'}
          </Button>
        }
      >
        <Dragger
          fileList={fileList}
          customRequest={handleUpload}
          onPreview={handlePreview}
          onRemove={handleRemove}
          beforeUpload={beforeUpload}
          accept="image/*"
          maxCount={1}
          listType="picture-card"
        >
          <p className="ant-upload-drag-icon">
            <InboxOutlined />
          </p>
          <p className="ant-upload-text">点击或拖拽图片到此区域上传</p>
          <p className="ant-upload-hint">支持单个图片上传，文件大小不超过10MB</p>
        </Dragger>
      </Card>

      {analyzing && (
        <Card title="分析中..." style={{ marginBottom: '20px' }}>
          <div className="loading-section">
            <Spin size="large" />
            <p>正在分析图片内容，请稍候...</p>
          </div>
        </Card>
      )}

      {/* 错误提示和重试区域 */}
      {analysisError && !analyzing && (
        <Card
          title="分析失败"
          style={{ marginBottom: '20px', borderColor: '#ff4d4f' }}
          extra={
            <Space>
              {analysisError.includes('Token权限不足') && (
                <Button
                  type="link"
                  size="small"
                  onClick={() => window.open('https://coze.cn/open/oauth/pats', '_blank')}
                >
                  🔗 管理Token权限
                </Button>
              )}
              <Button type="primary" danger onClick={retryAnalysis} disabled={!lastUploadedFile}>
                🔄 重试分析
              </Button>
            </Space>
          }
        >
          <div>
            <div style={{ color: '#ff4d4f', marginBottom: '12px' }}>
              <strong>错误信息：</strong>
              {analysisError.split(' - ')[0]}
            </div>

            {analysisError.includes(' - ') && (
              <div
                style={{
                  background: '#fff2f0',
                  padding: '12px',
                  borderRadius: '6px',
                  border: '1px solid #ffccc7',
                  marginBottom: '12px',
                }}
              >
                <div style={{ color: '#cf1322', fontWeight: 'bold', marginBottom: '8px' }}>
                  🔧 解决方案：
                </div>
                <div style={{ color: '#595959', lineHeight: '1.6' }}>
                  {analysisError.split(' - ')[1]}
                </div>
              </div>
            )}

            {analysisError.includes('Token权限不足') && (
              <div
                style={{
                  background: '#f6ffed',
                  padding: '12px',
                  borderRadius: '6px',
                  border: '1px solid #b7eb8f',
                }}
              >
                <div style={{ color: '#389e0d', fontWeight: 'bold', marginBottom: '8px' }}>
                  📋 权限配置步骤：
                </div>
                <ol style={{ color: '#595959', margin: 0, paddingLeft: '20px' }}>
                  <li>
                    访问{' '}
                    <a
                      href="https://coze.cn/open/oauth/pats"
                      target="_blank"
                      rel="noopener noreferrer"
                    >
                      Coze Token管理页面
                    </a>
                  </li>
                  <li>检查Token是否有访问目标Bot的权限</li>
                  <li>如需要，重新生成具有正确权限的Token</li>
                  <li>更新配置中的Token并重试</li>
                </ol>
              </div>
            )}

            <p style={{ color: '#666', fontSize: '14px', marginTop: '12px', marginBottom: 0 }}>
              💡 提示：配置正确后点击重试按钮，无需重新上传图片。
            </p>
          </div>
        </Card>
      )}

      {analysisResult && (
        <Card
          title="分析结果"
          className="analysis-result"
          style={{ marginBottom: '20px' }}
          extra={
            <Button
              icon={<EyeOutlined />}
              onClick={() => handlePreview({ url: analysisResult.imageUrl } as UploadFile)}
            >
              查看图片
            </Button>
          }
        >
          <div style={{ display: 'flex', gap: '20px' }}>
            <div style={{ flex: 1 }}>
              <div className="result-meta">
                <Text strong>分析时间：</Text>
                {new Date(analysisResult.timestamp).toLocaleString()}
              </div>
              <Paragraph>
                <Text strong>分析内容：</Text>
              </Paragraph>
              <div className="result-content">{analysisResult.content}</div>
            </div>
          </div>
        </Card>
      )}

      {/* 调试日志区域 */}
      {isDebugMode && logs.length > 0 && (
        <Card
          title="调试日志"
          style={{ marginBottom: '20px' }}
          extra={
            <Space>
              <Button size="small" onClick={copyLogs}>
                📋 复制日志
              </Button>
              <Button size="small" onClick={clearLogs}>
                🗑️ 清空日志
              </Button>
            </Space>
          }
        >
          <div
            style={{
              maxHeight: '300px',
              overflow: 'auto',
              background: '#f5f5f5',
              padding: '12px',
              borderRadius: '4px',
              fontFamily: 'monospace',
              fontSize: '12px',
              lineHeight: '1.4',
            }}
          >
            {logs.map((log, index) => (
              <div key={index} style={{ marginBottom: '4px', wordBreak: 'break-all' }}>
                {log}
              </div>
            ))}
          </div>
        </Card>
      )}

      {/* 图片预览模态框 */}
      <Image
        width={200}
        style={{ display: 'none' }}
        src={previewImage}
        preview={{
          visible: previewVisible,
          src: previewImage,
          onVisibleChange: visible => setPreviewVisible(visible),
        }}
      />
    </div>
  )
}

export default CozeImageAnalyzer
